﻿using System;
using System.IO;
using System.Linq;
using System.Xml;
using System.Xml.Serialization;

namespace YaP.Library
{
    internal class ServerFactory
    {
        public readonly string ServerFilePath;

        public NetworkList WorkingList;

        #region Private Methods

        private void WriteToFile()
        {
            XmlSerializer xmls = new XmlSerializer(typeof (NetworkList));
            XmlTextWriter writer = new XmlTextWriter(ServerFilePath, System.Text.Encoding.UTF8);

            xmls.Serialize(writer, WorkingList);
            writer.Close();
        }

        private NetworkList ReadFromFile()
        {
            XmlSerializer xmls = new XmlSerializer(typeof (NetworkList));


            XmlReader reader = null;
            try
            {
                reader = new XmlTextReader(new FileStream(ServerFilePath, FileMode.Open));
                NetworkList root = (NetworkList) xmls.Deserialize(reader);
                reader.Close();
                return root;
            }
            catch (InvalidOperationException)
            {
                //Typically, this exception is raised when there is a problem with the servers XML file format.
                reader.Close();
                CurrentServers = new NetworkList();
                return CurrentServers;
            }
            catch (FileNotFoundException)
            {
                //the Servers File has been deleted, YaP must have it. We're gonna create it.
                NetworkList NewServersRoot = new NetworkList();
                CurrentServers = new NetworkList();
                return CurrentServers;
            }
        }

        #endregion

        #region Public delegates

        public delegate void CollecModHandler(ServerFactory sender);

        #endregion

        #region Public Events

        public event CollecModHandler OnUpdated;

        #endregion

        #region Constructors

        public ServerFactory()
        {
            ServerFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\ServersList.xml";
            WorkingList = ReadFromFile();
        }

        public ServerFactory(string FilePath)
        {
            ServerFilePath = FilePath;
            WorkingList = ReadFromFile();
        }

        #endregion

        #region Public Properies

        public NetworkList CurrentServers
        {
            get { return WorkingList; }
            set { WorkingList = value; }
        }

        #endregion

        #region Public Methods

        public void Save()
        {
            WriteToFile();
        }

        public NetworkServerList GetGroup(Guid _GroupID)
        {
            return (from itm in WorkingList.Items
                    where itm.NetworkID == _GroupID
                    select itm).First();
        }

        public ServerItem GetServer(Guid _ServerID, Guid _GroupID)
        {
            NetworkServerList MyGroup = (from itm in WorkingList.Items
                                         where itm.NetworkID == _GroupID
                                         select itm).First();
            ServerItem MyServer = (from srv in MyGroup.ServerList
                                   where srv.ServerID == _ServerID
                                   select srv).First();
            return MyServer;
        }

        public void AddServer(string Name, string HostName, int port, Guid GroupId)
        {
            NetworkServerList MyGroup = (from itm in WorkingList.Items
                                         where itm.NetworkID == GroupId
                                         select itm).First();

            MyGroup.ServerList.Add(new ServerItem(Name, HostName, port));
            //OnUpdated(this);
        }

        public void EditServer(string Name, string HostName, int Port, Guid _GroupID, Guid _ServerID)
        {
            ServerItem MyItem = GetServer(_ServerID, _GroupID);
            MyItem.ServerName = Name;
            MyItem.ServerHost = HostName;
            MyItem.ServerPort = Port;
            //OnUpdated(this);
        }

        public void RemoveServer(Guid ServerId, Guid GroupID)
        {
            NetworkServerList MyGroup = (from itm in WorkingList.Items
                                         where itm.NetworkID == GroupID
                                         select itm).First();
            ServerItem MyServer = (from srv in MyGroup.ServerList
                                   where srv.ServerID == ServerId
                                   select srv).First();
            MyGroup.ServerList.Remove(MyServer);
            //OnUpdated(this);
        }

        public void AddGroup(string GroupName)
        {
            NetworkServerList NewGroup = new NetworkServerList();
            NewGroup.NetworkName = GroupName;
            WorkingList.Items.Add(NewGroup);
            //OnUpdated(this);
        }

        public void RemoveGroup(Guid GroupId)
        {
            NetworkServerList MyGroup = (from itm in WorkingList.Items
                                         where itm.NetworkID == GroupId
                                         select itm).First();
            WorkingList.Items.Remove(MyGroup);
            //OnUpdated(this);
        }

        #endregion
    }
}